package com.ruoyi.mobile.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.constant.AliyunConstant;
import com.ruoyi.common.core.redis.RedisUtils;
import com.ruoyi.common.utils.JsonUtil;
import com.ruoyi.mobile.domain.*;
import com.ruoyi.mobile.mapper.*;
import com.ruoyi.mobile.model.bo.MessageBo;
import com.ruoyi.mobile.model.bo.UserPrescriptionBo;
import com.ruoyi.mobile.model.request.LessonPointPrescriptionRequest;
import com.ruoyi.mobile.model.vo.UserPrescriptionVo;
import com.ruoyi.mobile.service.ICronService;
import com.ruoyi.system.service.ISysConfigService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import static java.util.Arrays.asList;

@Service
public class CronServiceImpl implements ICronService {

    private static final Logger logger = LoggerFactory.getLogger(CronServiceImpl.class);

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CheckinRecordMapper checkinRecordMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private MessageMapper messageMapper;

    @Autowired
    private LessonPrescriptionMapper lessonPrescriptionMapper;

    @Autowired
    private UserPrescriptionMapper userPrescriptionMapper;

    @Autowired
    private UserPrescriptionItemMapper userPrescriptionItemMapper;

    @Autowired
    private UserPointMapper userPointMapper;

    @Autowired
    private LessonPointPrescriptionMapper lessonPointPrescriptionMapper;


    /**
     * 每天凌晨1点执行，更新用户的坚持打卡天数
     */
    public void checkUserGoonCount() {
        //获取用户总数
        Integer count = userMapper.selectUserCount();
        Integer pageSize = 50;
        Integer page = (int)Math.ceil((double)count/pageSize);
        Integer checkinCount = 0;
        //昨天的时间
        LocalDate yesterday = LocalDateTime.now().plusDays(1).toLocalDate();

        for (int i=0; i<page; i++) {
            Integer offset = i*pageSize;
            List<Integer> userIds = userMapper.selectUserIdListByPage(offset, pageSize);
            for (Integer userId : userIds) {
                //检查用户昨天是否打卡，如果打卡了，坚持天数加1，如果没有打卡，坚持天数归0
                checkinCount = checkinRecordMapper.getCheckinRecordCountByDate(yesterday, userId);
                if (checkinCount > 0) {
                    //昨天打卡了
                    userMapper.addGoonCount(userId);
                } else {
                    //昨天没打卡
                    userMapper.resetGoonCount(userId);
                }
            }
        }
    }

    /**
     * 每分钟执行一次，把聊天的消息写入数据库
     */
    public void saveMsg() {
        int num = 1;
        List<Message> msgList = new ArrayList<Message>();
        while (true) {
            Object object = redisUtils.lPop("msgList");
            if (object == null) {
                if (msgList.size() > 0) {
                    messageMapper.insertList(msgList);
                }
                break;
            }
            if (num > 100) {
                if (msgList.size() > 0) {
                    messageMapper.insertList(msgList);
                }
                break;
            }
            num += 1;
            MessageBo messageBo = JsonUtil.parseObject((String) object, MessageBo.class);
            Message message = new Message();
            if (1 == messageBo.getFromAdmin()) {
                //是后台管理员发送给小程序用户
                message.setUserId(messageBo.getToUserId());
                message.setSysUserId(messageBo.getFromUserId());
                message.setSource(1);
                message.setSysUserReadFlag(1);
                message.setUserReadFlag(0);
            } else {
                //小程序用户发送给后台管理员
                message.setUserId(messageBo.getFromUserId());
                message.setSysUserId(messageBo.getToUserId());
                message.setSource(0);
                message.setUserReadFlag(1);
                message.setSysUserReadFlag(0);
            }
            message.setType(messageBo.getType());
            message.setContent(messageBo.getMsg());
            message.setSendTime(messageBo.getSendTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
            message.setCreateTime(LocalDateTime.now());
            msgList.add(message);
            if (msgList.size()>= 30) {
                messageMapper.insertList(msgList);
                msgList = new ArrayList<Message>();
            }

        }
    }

    /**
     * 每天凌晨1点执行一次，给已经写了手术时间的用户推送前九周的运动处方
     */
    public void deployLesson() throws ParseException {
        logger.info("tuisong kecheng 给已经写了手术时间的用户推送运动处方 start");
        //获取标准处方
        List<LessonPrescription> list = lessonPrescriptionMapper.selectNineWeekLessonPrescriptionList();
        Map<Integer, LessonPrescription> lessonPrescriptionMap = new HashMap<Integer, LessonPrescription>();
        for (LessonPrescription lessonPrescription : list) {
            Integer week = lessonPrescription.getWeek();
            lessonPrescriptionMap.put(week, lessonPrescription);
        }

        //获取用户总数
        Integer count = userMapper.selectBindCount();
        Integer pageSize = 50;
        Integer page = (int)Math.ceil((double)count/pageSize);
        LocalDate today = LocalDate.now();
        LocalDate yesterday = today.minusDays(1);

        for (int i=0; i<page; i++) {
            Integer offset = i*pageSize;
            List<User> userList = userMapper.selectBindUserListByPage(offset, pageSize);
            for (User user : userList) {
                //标准课程就以手术时间为准，打分的就以第一次打分时间为准
                //获取用户的手术时间
                LocalDateTime operationTime = user.getOperationTime(); //手术时间
                Integer standWeek = 0;
                int yesterdayOfWeek = yesterday.getDayOfWeek().getValue();
                LocalDate thisWeekStartDate = yesterday.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); // 本周的第一天
                LocalDate thisWeekWednesday = thisWeekStartDate.plusDays(2); // 加上2天，得到周三
                LocalDate lastWeekThursday = thisWeekStartDate.plusDays(-4); // 减去4天，得到上周四
                LocalDate thisWeekThursday = thisWeekStartDate.plusDays(3); // 加上3天，得到本周四
                LocalDate thisWeekEndDate = thisWeekStartDate.plusDays(6); // 加上6天，得到本周的最后一天
                LocalDate nextWeekWednesday = thisWeekThursday.plusDays(6); // 本周四加上6天，得到下周三
                LocalDate nextWeekStartDate = thisWeekStartDate.plusDays(7); // 本周一加上7天，得到下周一

                //检查用户现在是标准课程的第几周
                if (operationTime != null) {
                    LocalDate trainStartDate = LocalDateTimeUtil.offset(operationTime,1, ChronoUnit.DAYS).toLocalDate();
                    //计算相差天数
                    long betweenDays = LocalDateTimeUtil.between(trainStartDate.atStartOfDay(), LocalDateTime.now().toLocalDate().atStartOfDay(), ChronoUnit.DAYS);
                    if (betweenDays < 0) {
                        logger.info("tuisong kecheng 不推送课程 相差天数不对 用户id: " + user.getId().toString() + "  相差天数：" + String.valueOf(betweenDays));
                        continue;
                    }
                    //看看现在是第几周
                    Integer week = Math.toIntExact(betweenDays / 7);
                    week += 1;
                    standWeek = week;
                    if (week > 1) {
                        for (i=1; i<week; i++) {
                            handleButui(lessonPrescriptionMap, user, i, LocalDateTimeUtil.offset(operationTime,i, ChronoUnit.WEEKS).toLocalDate());
                        }
                    }
                    if (week <= 9) {
                        logger.info("tuisong kecheng 推送课程 第" + week + "周  用户id: " + user.getId().toString() + "   相差天数：" + String.valueOf(betweenDays));
                        //指定周次运动处方
                        boolean isTuisongSuccess = deployLessonByWeek(lessonPrescriptionMap, user.getId(), week, user, today, false);
                        //推送课程完毕，给用户发送短信
                        if (isTuisongSuccess && !StrUtil.isBlank(user.getPhone())) {
                            sendMsg(AliyunConstant.LESSON_NOTICE_TEMPLATE_CODE, user.getPhone());
                        }
                    }
                }


                //获取最新的一次打分记录
                UserPoint userPoint = userPointMapper.selectLastUserPointByUserId(user.getId());
                if (userPoint == null) {
                    //如果userPoint为null表明没有打分，那就不推送课程
                    if ( standWeek > 9) {
                        logger.info("tuisong kecheng 不推送课程 按照手术时间 第" + standWeek + "周  用户id: " + user.getId().toString() + "  没有打分 不推送课程");
                    }
                    continue;
                }
                //检查上一次推送课程的记录
                UserPrescription lastUserPrescription = userPrescriptionMapper.selectLastUserPrescription(user.getId());
                Integer week = 10;
                //每次推送的时候就按照上次的周次加1
                if (lastUserPrescription != null && lastUserPrescription.getWeek() != null) {
                    week = lastUserPrescription.getWeek() + 1;
                }
                if (9 >= week) {
                    logger.info("tuisong kecheng 不推送课程 按照手术时间 第" + standWeek + "周  用户id: " + user.getId().toString() + "  出现了打分课程周次小于9");
                    continue;
                }

                //看看昨天是本周的第几周，因为是凌晨执行任务，所以处理的是昨天打分的数据
                //打分的时候，如果是周一，二，三打得分，那么就推送本周的课程，如果是周四，五，六，日打得分，就推送下一周的课程
                if (1 == yesterdayOfWeek || 2 == yesterdayOfWeek || 3 == yesterdayOfWeek) {
                    //检查本周有没有推送课程
                    UserPrescription thisWeekPrescription = userPrescriptionMapper.selectUserPrescriptionByStartDate(user.getId(), thisWeekStartDate);
                    if (thisWeekPrescription != null) {
                        //本周课程已经推送了，就不处理了
                        continue;
                    }
                    //检查有没有为本周课程提供依据的打分
                    //打分的时候，如果是周一，二，三打得分，那么就推送本周的课程，如果是周四，五，六，日打得分，就推送下一周的课程
                    //所以上周四到本周三的打分，就是本周推送课程的打分依据
                    UserPoint thisWeekUserPoint = userPointMapper.selectUserPointByDate(user.getId(), lastWeekThursday, thisWeekWednesday);
                    //如果有一周没打分，到了周三都没打分，那么如果周四打分的话，都是推下周的课程了，本周的课程就空了，这个不行，必须推本周的课程，就按照上周的课程来
                    if (thisWeekUserPoint == null) {
                        if (1 == yesterdayOfWeek || 2 == yesterdayOfWeek) {
                            //到了周一，周二没打本周的分，没事，还有周三，周三是最后的机会
                            continue;
                        }
                        //周三还没打分，那就推送上一周的课程
                        if (lastUserPrescription != null) {
                            //指定分数运动处方
                            UserPoint lastWeekUserPoint = userPointMapper.selectUserPointById(lastUserPrescription.getPointId());
                            boolean isTuisongSuccess = deployLessonByPoint(user.getId(), week, user, thisWeekStartDate, lastWeekUserPoint);
                            //推送课程完毕，给用户发送短信
                            if (isTuisongSuccess && !StrUtil.isBlank(user.getPhone())) {
                                sendMsg(AliyunConstant.LESSON_NOTICE_TEMPLATE_CODE, user.getPhone());
                            }
                        }
                    } else {
                        //本周有打分，那就直接按照打分推送课程了
                        logger.info("tuisong kecheng 推送课程 第" + week + "周  用户id: " + user.getId().toString());
                        //指定分数运动处方
                        boolean isTuisongSuccess = deployLessonByPoint(user.getId(), week, user, thisWeekStartDate, thisWeekUserPoint);
                        //推送课程完毕，给用户发送短信
                        if (isTuisongSuccess && !StrUtil.isBlank(user.getPhone())) {
                            sendMsg(AliyunConstant.LESSON_NOTICE_TEMPLATE_CODE, user.getPhone());
                        }
                    }
                } else {
                    //检查有没有为下周课程提供依据的打分
                    //所以本周四到下周三的打分，就是下周推送课程的打分依据
                    UserPoint nextWeekUserPoint = userPointMapper.selectUserPointByDate(user.getId(), thisWeekThursday, nextWeekWednesday);
                    if (nextWeekUserPoint == null) {
                        continue;
                    }
                    //检查下周有没有推送课程
                    UserPrescription thisWeekPrescription = userPrescriptionMapper.selectUserPrescriptionByStartDate(user.getId(), nextWeekStartDate);
                    if (thisWeekPrescription != null) {
                        //本周课程已经推送了，就不处理了
                        continue;
                    }
                    //下周有打分依据，那就直接按照打分推送课程了
                    logger.info("tuisong kecheng 推送课程 第" + week + "周  用户id: " + user.getId().toString());
                    //指定分数运动处方
                    boolean isTuisongSuccess = deployLessonByPoint(user.getId(), week, user, nextWeekStartDate, nextWeekUserPoint);
                    //推送课程完毕，给用户发送短信
                    if (isTuisongSuccess && !StrUtil.isBlank(user.getPhone())) {
                        sendMsg(AliyunConstant.LESSON_NOTICE_TEMPLATE_CODE, user.getPhone());
                    }
                }
            }
        }
        logger.info("tuisong kecheng 给已经写了手术时间的用户推送运动处方 end");
    }

    /**
     * 每天早上5点执行一次，三天不打卡的用户进行提醒
     */
    public void sendUnTrainNoticeMessage() {
        logger.info("daka tixing 打卡提醒 start");
        //获取工作人员手机号
        String alarmPhoneStr = configService.selectConfigByKey("system.checkin.alarm.phone");
        List<String> alarmPhones = new ArrayList<>();
        if (!StrUtil.isBlank(alarmPhoneStr)) {
            String[] phones = alarmPhoneStr.split(",");
            for (int i = 0; phones != null && i < phones.length; i++) {
                alarmPhones.add(phones[i]);
            }
        }
        logger.info("daka tixing 打卡提醒 工作人员手机号：");
        System.out.println(alarmPhones);

        LocalDateTime yesterday = LocalDateTimeUtil.offset(LocalDateTime.now(),-1, ChronoUnit.DAYS);
        LocalDateTime beforeYesterday = LocalDateTimeUtil.offset(LocalDateTime.now(),-2, ChronoUnit.DAYS);
        LocalDateTime startDay = LocalDateTimeUtil.offset(LocalDateTime.now(),-3, ChronoUnit.DAYS);
        //获取用户总数
        Integer count = userMapper.selectBindCount();
        Integer pageSize = 50;
        Integer page = (int)Math.ceil((double)count/pageSize);
        for (int i=0; i<page; i++) {
            Integer offset = i*pageSize;
            List<User> userList = userMapper.selectBindUserListByPage(offset, pageSize);
            for (User user : userList) {
                //获取用户的手术时间
                LocalDateTime operationTime = user.getOperationTime(); //手术时间
                if (operationTime == null) {
                    logger.info("daka duanxing tixing no operationTime 打卡短信没手术时间不提醒 用户id: " + user.getId().toString());
                    continue; //没有手术时间就不推课程，也就不用提醒打卡了
                }
                //检查过去3天有没有课程，有才进行提醒
                UserPrescriptionBo userPrescriptionBo = userPrescriptionMapper.getUserPrescriptionByDate(user.getId(), startDay);
                if (userPrescriptionBo == null) {
                    userPrescriptionBo = userPrescriptionMapper.getUserPrescriptionByDate(user.getId(), beforeYesterday);
                    if (userPrescriptionBo == null) {
                        userPrescriptionBo = userPrescriptionMapper.getUserPrescriptionByDate(user.getId(), yesterday);
                    }
                }
                if (userPrescriptionBo == null) {
                    logger.info("daka duanxing tixing no lesson 打卡短信没课程不提醒 用户id: " + user.getId().toString());
                    continue;  //如果过去3天都没有课程，就不提醒了
                }

                //检查用户是否3天未打卡
                Integer checkinCount = checkinRecordMapper.getUserCheckinCountByDate(user.getId(), startDay, yesterday);
                if (checkinCount == null || checkinCount == 0) {
                    if (!StrUtil.isBlank(user.getPhone())) {
                        //3天不打卡，切手机号不为空，就发短信提醒用户要进行运动了
                        logger.info("daka duanxing tixing 打卡短信提醒 " + user.getPhone());
                        sendMsg(AliyunConstant.UNTRAIN_NOTICE_TEMPLATE_CODE, user.getPhone());
                        //给工作人员也发个短信提醒
                        String templateParam = "";
                        try {
                            HashMap templateParamMap = new HashMap<String, String>();
                            templateParamMap.put("name", user.getPhone());
                            ObjectMapper objectMapper = new ObjectMapper();
                            templateParam = objectMapper.writeValueAsString(templateParamMap);
                        } catch (Exception e ){
                            logger.error("daka duanxing tixing 工作人员打卡短信提醒 ", e);
                        }
                        for (String phone : alarmPhones) {
                            logger.info("daka duanxing tixing 工作人员打卡短信提醒 " + phone);
                            sendMsg(AliyunConstant.GONGZUORENYUAN_UNTRAIN_NOTICE_TEMPLATE_CODE, templateParam, phone);
                        }
                    }
                }
            }
        }
        logger.info("daka tixing 打卡提醒 end");
    }



    /**
     * 发送短信
     */
    public void sendMsg(String templateCode, String phoneNumber) {
        try {
            Client client = createClient(AliyunConstant.ACCESS_KEY_ID, AliyunConstant.ACCESS_KEY_SECRET);
            SendSmsRequest sendSmsRequest = new SendSmsRequest();
            sendSmsRequest.setPhoneNumbers(phoneNumber);
            sendSmsRequest.setSignName(AliyunConstant.SIGN_NAME);
            sendSmsRequest.setTemplateCode(templateCode);

            // 复制代码运行请自行打印 API 的返回值
            SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
            if (sendSmsResponse.getBody() != null && sendSmsResponse.getBody().getCode() != null && "OK".equals(sendSmsResponse.getBody().getCode())) {
                //发送成功
                logger.error("短信发送成功：===" + phoneNumber);
            } else {
                logger.error("短信发送失败");
            }
        } catch (TeaException error) {
            logger.error("短信发送失败：===", error);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            logger.error("短信发送失败：===", error);
        }
    }

    public void sendMsg(String templateCode, String templateParam, String phoneNumber) {
        try {
            Client client = createClient(AliyunConstant.ACCESS_KEY_ID, AliyunConstant.ACCESS_KEY_SECRET);
            SendSmsRequest sendSmsRequest = new SendSmsRequest();
            sendSmsRequest.setPhoneNumbers(phoneNumber);
            sendSmsRequest.setSignName(AliyunConstant.SIGN_NAME);
            sendSmsRequest.setTemplateCode(templateCode);
            sendSmsRequest.setTemplateParam(templateParam);

            // 复制代码运行请自行打印 API 的返回值
            SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
            if (sendSmsResponse.getBody() != null && sendSmsResponse.getBody().getCode() != null && "OK".equals(sendSmsResponse.getBody().getCode())) {
                //发送成功
                logger.error("短信2发送成功：===" + phoneNumber);
            } else {
                logger.error("短信2发送失败");
            }
        } catch (TeaException error) {
            logger.error("短信2发送失败：===", error);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            logger.error("短信2发送失败：===", error);
        }
    }

    public Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        Config config = new Config()
                // 您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // 访问的域名
        config.endpoint = AliyunConstant.ENDPOINT;
        return new Client(config);
    }

    public boolean deployLessonByPoint(Integer userId, Integer week, User user, LocalDate startTrainDate, UserPoint userPoint) {
        //有打分就开始推送
        if (userPoint == null) {
            logger.info("tuisong kecheng 不推送课程 没打分 第" + week + "周 用户id: " + user.getId().toString());
            return false;
        }
        //检查用户是否已经推过课程，已经推过就不推了
        Integer userPrescriptionCount = userPrescriptionMapper.getUserPrescriptionByWeek(userId, week);
        if (userPrescriptionCount >= 1) {
            logger.info("tuisong kecheng 不推送课程 已经推送过了 第" + week + "周 用户id: " + user.getId().toString() + "  分数：" + userPoint.getScore().toString());
            return false;
        }
        //如果这个分数没有设置课程，也不推
        LessonPointPrescription lessonPointPrescription = lessonPointPrescriptionMapper.selectLessonPointPrescriptionByPoint(userPoint.getScore());
        if (lessonPointPrescription == null) {
            logger.info("tuisong kecheng 不推送课程 指定分数没课程 第" + week + "周 用户id: " + user.getId().toString() + "  分数：" + userPoint.getScore().toString());
            return false;
        }
        //指定分数处方
        UserPrescription userPrescription = new UserPrescription();
        userPrescription.setUserId(userId);
        userPrescription.setWeek(week);
        userPrescription.setTrainTime(startTrainDate);
        userPrescription.setType(2);
        userPrescription.setPointId(lessonPointPrescription.getId());
        userPrescription.setCreateTime(new Date());
        userPrescriptionMapper.insertUserPrescription(userPrescription);

        List<LessonPointPrescriptionItem> lessonPointPrescriptionItemList = lessonPointPrescription.getLessonPointPrescriptionItems();
        for (LessonPointPrescriptionItem lessonPointPrescriptionItem : lessonPointPrescriptionItemList) {
            UserPrescriptionItem userPrescriptionItem = new UserPrescriptionItem();
            userPrescriptionItem.setItemId(lessonPointPrescriptionItem.getId());
            userPrescriptionItem.setPrescriptionId(userPrescription.getId());
            userPrescriptionItemMapper.insertUserPrescriptionItem(userPrescriptionItem);
        }

        userPointMapper.updateDeployed(userPoint.getId());
        logger.info("tuisong kecheng 推送课程成功 第" + week + "周 用户id: " + user.getId().toString() + "  分数：" + userPoint.getScore().toString());
        return true;
    }


    public boolean deployLessonByWeek(Map<Integer, LessonPrescription> lessonPrescriptionMap, Integer userId, Integer week, User user, LocalDate startTrainDate, boolean butui) {
        if (!lessonPrescriptionMap.containsKey(week)) {
            if (butui) {
                logger.info("butui tuisong kecheng 不推送课程 未配置课程 第" + week + "周 用户id: " + user.getId().toString());
            } else {
                logger.info("tuisong kecheng 不推送课程 未配置课程 第" + week + "周 用户id: " + user.getId().toString());
            }
            return false;  //未配置这一周的运动处方就跳过
        }
        //这里要记得，打分,推课程，华为运动周统计的时间 必须是一致的

        //检查用户是否已经推过课程，已经推过就不推了
        Integer userPrescriptionCount = userPrescriptionMapper.getUserPrescriptionByWeek(userId, week);
        if (userPrescriptionCount >= 1) {
            if (butui) {
                logger.info("butui tuisong kecheng 不推送课程 已推送过课程 第" + week + "周 用户id: " + user.getId().toString());
            } else {
                logger.info("tuisong kecheng 不推送课程 已推送过课程 第" + week + "周 用户id: " + user.getId().toString());
            }
            return false;
        }

        //标准处方
        UserPrescription userPrescription = new UserPrescription();
        userPrescription.setUserId(user.getId());
        userPrescription.setWeek(week);
        userPrescription.setTrainTime(startTrainDate);
        userPrescription.setType(1);
        userPrescription.setWeekType(week);
        userPrescription.setCreateTime(new Date());
        userPrescriptionMapper.insertUserPrescription(userPrescription);

        LessonPrescription lessonPrescription = lessonPrescriptionMapper.selectLessonPrescriptionByWeek(week);
        List<LessonPrescriptionItem> lessonPrescriptionItemList = lessonPrescription.getLessonPrescriptionItems();
        for (LessonPrescriptionItem lessonPrescriptionItem : lessonPrescriptionItemList) {
            UserPrescriptionItem userPrescriptionItem = new UserPrescriptionItem();
            userPrescriptionItem.setItemId(lessonPrescriptionItem.getId());
            userPrescriptionItem.setPrescriptionId(userPrescription.getId());
            userPrescriptionItemMapper.insertUserPrescriptionItem(userPrescriptionItem);
        }
        if (butui) {
            logger.info("butui tuisong kecheng 推送课程成功 第" + week + "周 用户id: " + user.getId().toString());
        } else {
            logger.info("tuisong kecheng 推送课程成功 第" + week + "周 用户id: " + user.getId().toString());
        }
        return true;
    }


    public void handleButui(Map<Integer, LessonPrescription> lessonPrescriptionMap, User user, Integer week, LocalDate startTrainDate) {
        if (week <= 9) {
            //指定周次运动处方
            deployLessonByWeek(lessonPrescriptionMap, user.getId(), week, user, startTrainDate, true);
        }
    }

    public void buTuiLesson() {
        //获取标准处方
        List<LessonPrescription> list = lessonPrescriptionMapper.selectNineWeekLessonPrescriptionList();
        Map<Integer, LessonPrescription> lessonPrescriptionMap = new HashMap<Integer, LessonPrescription>();
        for (LessonPrescription lessonPrescription : list) {
            Integer week = lessonPrescription.getWeek();
            lessonPrescriptionMap.put(week, lessonPrescription);
        }
        List<Integer> userIds = asList(57,60,94,133);

        for (Integer userId : userIds) {
            //检查用户现在是第几周
            //获取用户的手术时间
            User user = userMapper.selectUserById(userId);
            LocalDateTime operationTime = user.getOperationTime(); //手术时间
            if (operationTime == null) {
                continue; //没有手术时间就不推课程
            }
            LocalDate trainStartDate = LocalDateTimeUtil.offset(operationTime,1, ChronoUnit.DAYS).toLocalDate();

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate startDate = LocalDate.parse("2023-02-07", formatter);
            LocalDate endDate = LocalDate.parse("2023-04-25", formatter);
            for(LocalDate currentdate = startDate; currentdate.isBefore(endDate) || currentdate.isEqual(endDate); currentdate= currentdate.plusDays(1)){
                //计算相差天数
                long betweenDays = LocalDateTimeUtil.between(trainStartDate.atStartOfDay(), currentdate.atStartOfDay(), ChronoUnit.DAYS);
                LocalDate today = currentdate;
                if (betweenDays < 0) {
                    continue;
                }
                //看看现在是第几周
                Integer week = Math.toIntExact(betweenDays / 7);
                week += 1;
                if (!lessonPrescriptionMap.containsKey(week)) {
                    System.out.println("用户openid：" + user.getOpenid() + " 未配置这周课程");
                    continue;  //未配置这一周的运动处方就跳过
                }
                //这里要记得，打分,推课程，华为运动周统计的时间 必须是一致的

                //检查用户是否已经推过课程，已经推过就不推了
                Integer userPrescriptionCount = userPrescriptionMapper.getUserPrescriptionByWeek(userId, week);
                if (userPrescriptionCount >= 1) {
                    System.out.println("用户openid：" + user.getOpenid() + " 已经推过了");
                    continue;
                }

                //标准处方
                UserPrescription userPrescription = new UserPrescription();
                userPrescription.setUserId(userId);
                userPrescription.setWeek(week);
                userPrescription.setTrainTime(today);
                userPrescription.setType(1);
                userPrescription.setWeekType(week);
                userPrescription.setCreateTime(new Date());
                userPrescriptionMapper.insertUserPrescription(userPrescription);

                LessonPrescription lessonPrescription = lessonPrescriptionMapper.selectLessonPrescriptionByWeek(week);
                List<LessonPrescriptionItem> lessonPrescriptionItemList = lessonPrescription.getLessonPrescriptionItems();
                for (LessonPrescriptionItem lessonPrescriptionItem : lessonPrescriptionItemList) {
                    UserPrescriptionItem userPrescriptionItem = new UserPrescriptionItem();
                    userPrescriptionItem.setItemId(lessonPrescriptionItem.getId());
                    userPrescriptionItem.setPrescriptionId(userPrescription.getId());
                    userPrescriptionItemMapper.insertUserPrescriptionItem(userPrescriptionItem);
                }
            }


        }

    }

    /**
     * 检查某一周是否有推送过课程
     * @param userId
     * @param week
     * @return
     */
    public boolean checkIsDeployByWeek(Integer userId, Integer week) {
        Integer userPrescriptionCount = userPrescriptionMapper.getUserPrescriptionByWeek(userId, week);
        if (userPrescriptionCount >= 1) {
            return true;
        }
        return false;
    }
}
